package com.example.demo.alex.security;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Iterator;

/**
 * @ClassName AccessDecisionManagerImpl
 * @Description TODO
 * @Author zjg
 * @Date 2018/12/2519:15
 * @Version 2.0
 */
@Component
//Security需要用到一个实现了AccessDecisionManager接口的类
//类功能：根据当前用户的信息，和目标url涉及到的权限，判断用户是否可以访问
//判断规则：用户只要匹配到目标url权限中的一个role就可以访问
public class AccessDecisionManagerImpl implements AccessDecisionManager {
    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
        Iterator<ConfigAttribute> iterator=collection.iterator();
        while (iterator.hasNext()){
            ConfigAttribute ca=iterator.next();
            String needRole=ca.getAttribute();
            if("ROLE_LOGIN".equals(needRole)){
                if(authentication instanceof AnonymousAuthenticationToken){
                    throw new BadCredentialsException("未登录");
                }else
                    return;
            }
            //遍历当前用户的所有的权限
            Collection<? extends GrantedAuthority> authorities=authentication.getAuthorities();
            for (GrantedAuthority authority: authorities){
                if (authority.getAuthority().equals(needRole)){
                    return;
                }
            }
        }
        //执行到这里说明没有匹配到应有的权限
        throw new AccessDeniedException("权限不足");
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
